﻿using System;
using System.Collections.Generic;
using System.Threading;
using MugenInjection.Interface;

namespace MugenInjection.Scope
{
    /// <summary>
    ///     Represents the thread scope lifecycle.
    /// </summary>
    public sealed class ThreadScopeLifecycle : ScopeLifecycleBase
    {
        #region Fields

        private readonly Dictionary<int, object> _threadDictionary = new Dictionary<int, object>();

        #endregion

        #region Overrides of ScopeLifecycleBase

        /// <summary>
        ///     Resolves instance for the specified <see cref="IBindingContext" /> from scope.
        /// </summary>
        /// <returns>An instance of the service.</returns>
        protected override object GetObjectFromScope()
        {
#if NETFX_CORE
            int threadId = Environment.CurrentManagedThreadId;
#else
            int threadId = Thread.CurrentThread.ManagedThreadId;
#endif
            lock (Locker)
            {
                object service;
                if (!_threadDictionary.TryGetValue(threadId, out service))
                {
                    service = ResolveCurrentService();
                    _threadDictionary.Add(threadId, service);
                }
                return service;
            }
        }

        /// <summary>
        ///     Gets all created objects in the current scope.
        /// </summary>
        protected override IList<object> GetObjectsFromScope()
        {
            var objects = new object[_threadDictionary.Values.Count];
            _threadDictionary.Values.CopyTo(objects, 0);
            return objects;
        }

        /// <summary>
        ///     Clears the current scope.
        /// </summary>
        protected override void ClearScope()
        {
            _threadDictionary.Clear();
        }

        #endregion
    }
}